﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ORMAC.CodeGen;
namespace ORMAC.UnitTest
{
    [TestFixture]
    public class ORMACTester
    {
        string TestDataCnn=Settings.Default.TestDBConnectionString;
        [Test]
        public void TestSingleClass(){
            IReader orm = new OReader();
            orm.SetConnectionString(TestDataCnn);
            var res = orm.LoadFromDatabase<Invoice>();
            
            
            foreach (var inv in res)
            {
                Console.Write(inv.InvoiceID+".");
                Console.WriteLine(inv.Description);
                Console.Write("\tBilledTo:" + inv.BilledTo.ID + ":");
                Console.WriteLine(inv.BilledTo.Name + " " + inv.BilledTo.Surname);
                Console.WriteLine("Items:");
                foreach(var item in inv.Items){
                    Console.Write("\t" + item.ID + ":");
                    Console.Write(item.Description);
                    Console.WriteLine("\t" + item.Price);

                }
                Console.WriteLine("Accounts:");
                foreach (var item in inv.GLAcounts)
                {
                    Console.Write("\t" + item.ID + ":");
                    Console.WriteLine(item.Name);
                }
            }
        }
        [Test]
        public void TestSchema()
        {
            IDBSchema schema = new SQLShema();
            List<TableInfo> res=schema.RetrieveSchema<TableInfo>(TestDataCnn);
            foreach (var table in res)
            {
                Console.WriteLine("Table:" + table.Name);
                foreach (var col in table.Columns)
                {
                    Console.Write("\tColumn:" + col.Name);
                    Console.WriteLine("(" + col.ColumnType.Name+")");
                }
                if (table.Joins != null)
                {
                    foreach (var j in table.Joins)
                    {
                        Console.WriteLine("\tJoin Tables:" + j.LeftTable + "," + j.RightTable);
                        Console.WriteLine("\tJoin Cols:" + j.LeftColumn + "," + j.RightColumn);
                    }
                }
                if (table.LinkJoins != null)
                {
                    foreach (var l in table.LinkJoins)
                    {
                        Console.WriteLine("\tLink Tables:" + l.LinkTable+","+l.ChildTable);
                        Console.WriteLine("\tLink Cols:" +l.ParentCol+","+l.LinkTableParentCol+","+l.LinkTableChildCol+","+l.ChildCol);
                    }
                }
            }
        }
        [Test]
        public void TestCodeGen()
        {
            IDBSchema schema = new SQLShema();
            List<TableInfo> res = schema.RetrieveSchema<TableInfo>(TestDataCnn);
            ICodeGenerator generator = new CodeGenerator();
            foreach (var table in res)
            {
                string str=generator.GenerateClass(TestDataCnn, "ORMAC.Test",table);
                Console.WriteLine(str);
            }
        }
        [Test]
        public void TestQuery()
        {
            string cnnString = TestDataCnn;
            IReader orm = new OReader();
            orm.SetConnectionString(cnnString);
            var res = orm.LoadFromDatabase<JoinInfo>();


            foreach (var inv in res)
            {
                Console.Write("Left:" +inv.LeftTable+"("+inv.LeftColumn+"),Right:"+inv.RightTable+"("+inv.RightColumn+")" );
            }
        }
        [Test]
        public void TestSPInfo()
        {
            IDBSchema schema = new SQLShema();
            List<TableInfo> res = schema.RetrieveSchema<TableInfo>(TestDataCnn);
            ICodeGenerator generator = new CodeGenerator();
            foreach (var table in res)
            {
                generator.GenerateClass(TestDataCnn, "ORMAC.Test", table);
            }
            List<SProcInfo> res1 = schema.RetrieveSchema<SProcInfo>(TestDataCnn);
            foreach (var table in res1)
            {
                generator.GenerateClass(TestDataCnn, "ORMAC.Test", table);
            }
            string str = generator.GenerateRepository(TestDataCnn, "ORMAC.Test");
            Console.WriteLine(str);
        }
        [Test]
        public void TestSingleClass2()
        {
            string cnnString = TestDataCnn;
            IReader orm = new OReader();
            orm.SetConnectionString(cnnString);
            var res = orm.LoadFromDatabase<Invoice>(a=>a.InvoiceID==1);


            foreach (var inv in res)
            {
                Console.Write(inv.InvoiceID + ".");
                Console.WriteLine(inv.Description);
                Console.Write("\tBilledTo:" + inv.BilledTo.ID + ":");
                Console.WriteLine(inv.BilledTo.Name + " " + inv.BilledTo.Surname);
                Console.WriteLine("Items:");
                foreach (var item in inv.Items)
                {
                    Console.Write("\t" + item.ID + ":");
                    Console.WriteLine(item.Description);
                    foreach (var color in item.Colors)
                    {
                        Console.WriteLine("\t\t" + color.Code);
                    }
                }
                Console.WriteLine("Accounts:");
                foreach (var item in inv.GLAcounts)
                {
                    Console.Write("\t" + item.ID + ":");
                    Console.WriteLine(item.Name);
                }
            }
        }
        [Test]
        public void TestExecSP_ListCustomers()
        {
            Repository r = new Repository(TestDataCnn);
            r.GetCustomerList();
        }
        [Test]
        public void TestExecSP_ListInvoices()
        {
            Repository r = new Repository(TestDataCnn);
            r.GetInvoices();
        }
        [Test]
        public void TestExecSP_SelectCustomer()
        {
            Repository r = new Repository(TestDataCnn);
            r.SelectCustomer(1);
        }
        [Test]
        public void TestExecSP_Scalar()
        {
            Repository r = new Repository(TestDataCnn);
            var res=r.GetTotalInvoice(1);
            Console.WriteLine("Result:" + res.ToString());
        }
        [Test]
        public void TestExecSP_1Output()
        {
            Repository r = new Repository(TestDataCnn);
            var res = r.GetTotalInvoice2(1);
            Console.WriteLine("Result:" + res.ToString());
        }
        [Test]
        public void TestContext0()
        {
            IReader orm = new OReader();
            orm.SetConnectionString(TestDataCnn);
            orm.LoadObject<Invoice>(i =>null);
            var res = orm.LoadFromDatabase<Invoice>(i => i.InvoiceID == 1);
            Assert.IsNull(res[0].BilledTo);
            Assert.IsNull(res[0].Items);
        }

        [Test]
        public void TestContext1()
        {
            IReader orm = new OReader();
            orm.SetConnectionString(TestDataCnn);
            orm.LoadObject<Invoice>(i => i.Items);
            var res = orm.LoadFromDatabase<Invoice>(i=>i.InvoiceID==1);
            Assert.IsNull(res[0].BilledTo);
            Assert.IsNotNull(res[0].Items);            
        }
        [Test]
        public void TestContext2()
        {
            IReader orm = new OReader();
            orm.SetConnectionString(TestDataCnn);
            orm.LoadObject<Invoice>(i => i.Items)
            .LoadObject<Invoice>(i => i.BilledTo)
            .LoadObject<Item>(i =>i.Colors);
            
            var res = orm.LoadFromDatabase<Invoice>(i => i.InvoiceID == 1);
            Assert.IsNotNull(res[0].BilledTo);
            Assert.IsNotNull(res[0].Items);
            Assert.IsNull(res[0].Items[0].ItemInvoice);
        }
    }
}
